home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection 1998 Fall: Game Toolkit / Disc.iso / SDKs / QuickTime Mac / ComponentIncludes / ComponentDispatchHelper.c next >
Encoding:
Text File  |  1998-03-27  |  14.2 KB  |  421 lines  |  [TEXT/MPS ]

  1. /*
  2.     File:        ComponentDispatchHelper.c
  3.  
  4.     Copyright:    © 1995-1997 by Apple Computer, Inc., all rights reserved.
  5.  
  6. */
  7.  
  8. // **** BEGIN: Error Checking the Required Macros
  9.  
  10. // Make sure BASENAME is defined
  11. #ifndef COMPONENT_BASENAME
  12.     #ifdef CALLCOMPONENT_BASENAME
  13.         #define COMPONENT_BASENAME()     CALLCOMPONENT_BASENAME()
  14.     #else
  15.         #error "COMPONENT_BASENAME or CALLCOMPONENT_BASENAME must be defined for ComponentDispatchHelper.c"
  16.     #endif
  17. #endif
  18.  
  19. // Make sure GLOBALS is defined
  20. #ifndef COMPONENT_GLOBALS
  21.     #ifdef CALLCOMPONENT_GLOBALS
  22.         #define COMPONENT_GLOBALS()     CALLCOMPONENT_GLOBALS()
  23.     #else
  24.         #error "COMPONENT_GLOBALS or CALLCOMPONENT_GLOBALS must be defined for ComponentDispatchHelper.c"
  25.     #endif
  26. #endif
  27.  
  28. // Make sure DISPATCH_FILE is defined
  29. #ifndef COMPONENT_DISPATCH_FILE
  30.     #error "COMPONENT_DISPATCH_FILE must be defined for ComponentDispatchHelper.c"
  31. #endif
  32.  
  33.  
  34. // Make sure UPP_PREFIX and SELECT_PREFIX are defined
  35. #if !defined(COMPONENT_UPP_SELECT_ROOT)  && !defined(COMPONENT_UPP_PREFIX) && !defined(COMPONENT_SELECT_PREFIX)
  36.     #error "COMPONENT_UPP_SELECT_ROOT or (COMPONENT_UPP_PREFIX and COMPONENT_SELECT_PREFIX) must be defined for ComponentDispatchHelper.c"
  37. #endif
  38. #ifdef COMPONENT_UPP_SELECT_ROOT
  39.     #if defined(COMPONENT_UPP_PREFIX) || defined(COMPONENT_SELECT_PREFIX)
  40.         #error "use only COMPONENT_UPP_SELECT_ROOT or (COMPONENT_UPP_PREFIX and COMPONENT_SELECT_PREFIX) for ComponentDispatchHelper.c"
  41.     #endif
  42. #else
  43.     #if !defined(COMPONENT_UPP_PREFIX) || !defined(COMPONENT_SELECT_PREFIX)
  44.         #error "COMPONENT_UPP_SELECT_ROOT or (COMPONENT_UPP_PREFIX and COMPONENT_SELECT_PREFIX) must be defined for ComponentDispatchHelper.c"
  45.     #endif
  46. #endif
  47. #ifndef COMPONENT_UPP_PREFIX
  48.     #ifndef COMPONENT_UPP_SELECT_ROOT
  49.         #error "COMPONENT_UPP_SELECT_ROOT or (COMPONENT_UPP_PREFIX and COMPONENT_SELECT_PREFIX) must be defined for ComponentDispatchHelper.c"
  50.     #else 
  51.         #define COMPONENT_UPP_PREFIX()        cdh_GLUE2(upp,COMPONENT_UPP_SELECT_ROOT())
  52.     #endif
  53. #endif
  54. #ifndef COMPONENT_SELECT_PREFIX
  55.     #ifndef COMPONENT_UPP_SELECT_ROOT
  56.         #error "COMPONENT_UPP_SELECT_ROOT or (COMPONENT_UPP_PREFIX and COMPONENT_SELECT_PREFIX) must be defined for ComponentDispatchHelper.c"
  57.     #else 
  58.         #define COMPONENT_SELECT_PREFIX()    cdh_GLUE2(k,COMPONENT_UPP_SELECT_ROOT())
  59.     #endif
  60. #endif
  61.     
  62. // Make sure SUBTYPE UPP_PREFIX and SELECT_PREFIX are defined correctly if they are used at all
  63. #if defined(COMPONENT_SUBTYPE_UPP_SELECT_ROOT) || defined(COMPONENT_SUBTYPE_UPP_PREFIX) || defined(COMPONENT_SUBTYPE_SELECT_PREFIX)
  64.     #ifdef COMPONENT_SUBTYPE_UPP_SELECT_ROOT
  65.         #if defined(COMPONENT_SUBTYPE_UPP_PREFIX) || defined(COMPONENT_SUBTYPE_SELECT_PREFIX)
  66.             #error "use only COMPONENT_SUBTYPE_UPP_PREFIX and COMPONENT_SUBTYPE_SELECT_PREFIX OR COMPONENT_SUBTYPE_UPP_SELECT_ROOT for ComponentDispatchHelper.c"
  67.         #endif
  68.     #else
  69.         #if !defined(COMPONENT_SUBTYPE_UPP_PREFIX) || !defined(COMPONENT_SUBTYPE_SELECT_PREFIX)
  70.             #error "COMPONENT_SUBTYPE_UPP_PREFIX and COMPONENT_SUBTYPE_SELECT_PREFIX OR COMPONENT_SUBTYPE_UPP_SELECT_ROOT must be defined for ComponentDispatchHelper.c"
  71.         #endif
  72.     #endif
  73.     #ifndef COMPONENT_SUBTYPE_UPP_PREFIX
  74.         #ifndef COMPONENT_SUBTYPE_UPP_SELECT_ROOT
  75.             #error "COMPONENT_SUBTYPE_UPP_PREFIX or COMPONENT_SUBTYPE_UPP_SELECT_ROOT must be defined for ComponentDispatchHelper.c"
  76.         #else 
  77.             #define COMPONENT_SUBTYPE_UPP_PREFIX()        cdh_GLUE2(upp,COMPONENT_SUBTYPE_UPP_SELECT_ROOT())
  78.         #endif
  79.     #endif
  80.     #ifndef COMPONENT_SUBTYPE_SELECT_PREFIX
  81.         #ifndef COMPONENT_SUBTYPE_UPP_SELECT_ROOT
  82.             #error "COMPONENT_SUBTYPE_SELECT_PREFIX or COMPONENT_SUBTYPE_UPP_SELECT_ROOT must be defined for ComponentDispatchHelper.c"
  83.         #else 
  84.             #define COMPONENT_SUBTYPE_SELECT_PREFIX()    cdh_GLUE2(k,COMPONENT_SUBTYPE_UPP_SELECT_ROOT())
  85.         #endif
  86.     #endif
  87. #endif
  88.  
  89. // **** END: Error Checking the Required Macros
  90.  
  91.  
  92. #if TARGET_OS_MAC
  93.     #define PASCAL_RTN    pascal
  94. #else
  95.     #define PASCAL_RTN
  96. #endif
  97. #if !TARGET_OS_MAC || TARGET_CPU_PPC
  98.     #define C_DISPATCH_WITH_GLOBALS    1
  99.     #define C_DISPATCH_WITH_SWITCH    0
  100. #elif TARGET_CPU_68K
  101.     #ifdef COMPONENT_C_DISPATCHER
  102.         #define C_DISPATCH_WITH_GLOBALS    0
  103.         #define C_DISPATCH_WITH_SWITCH    1
  104.     #else
  105.         #define C_DISPATCH_WITH_GLOBALS    0
  106.         #define C_DISPATCH_WITH_SWITCH    0
  107.     #endif
  108. #else
  109.     #error "I have no idea what kind of machine you are using"
  110. #endif
  111.  
  112. /*
  113.     C_DISPATCH_WITH_GLOBALS implies global storage for dispatch information 
  114.                             and procinfos returned by COMPONENTSELECTORLOOKUP
  115.     C_DISPATCH_WITH_SWITCH  implies no global storage, dispatch by switch
  116.                             and no procinfos returned by COMPONENTSELECTORLOOKUP
  117. */
  118.  
  119.     #define COMPONENTSELECTORLOOKUP ADD_BASENAME(FindRoutineUPP)
  120.  
  121. #ifdef COMPONENT_DISPATCH_MAIN
  122.     #define COMPONENT_DISPATCH_ENTRY main
  123. #else
  124.     #define COMPONENT_DISPATCH_ENTRY ADD_BASENAME(ComponentDispatch)
  125. #endif
  126.  
  127. #ifndef __COMPONENTS_K__
  128.     #include "Components.k.h"
  129. #endif
  130.  
  131. #define    kCOMPONENT_NOERROR    ((ComponentFunctionUPP)-2)
  132. #define    kCOMPONENT_ERROR    ((ComponentFunctionUPP)-1)
  133. #define    kCOMPONENT_DELEGATE    ((ComponentFunctionUPP)0)
  134.  
  135. #ifndef cdh_GLUE
  136.     #define cdh_GLUE(a,b)        a##b
  137. #endif
  138. #ifndef cdh_GLUE2
  139.     #define cdh_GLUE2(a,b)        cdh_GLUE(a,b)
  140. #endif
  141. #ifndef cdh_GLUE3
  142.     #define cdh_GLUE3(a,b,c)    cdh_GLUE2(cdh_GLUE2(a,b),c)
  143. #endif
  144.  
  145. #if TARGET_RT_LITTLE_ENDIAN
  146.     #define ComponentCallLittleEndian         ComponentCall
  147. #else
  148.     #define ComponentCallLittleEndian         ComponentDelegate
  149. #endif
  150.  
  151. #ifdef forPublicQTiRelease
  152.     #define ComponentQTiCall(procName)                ComponentCall(procName)
  153.     #define QTIComponentCall(procName)                ComponentCall(procName)
  154. #endif
  155.  
  156. #define ADD_BASENAME(name) cdh_GLUE2(COMPONENT_BASENAME(),name)
  157.  
  158. #if C_DISPATCH_WITH_GLOBALS
  159.     PASCAL_RTN ComponentResult COMPONENT_DISPATCH_ENTRY(ComponentParameters *params, COMPONENT_GLOBALS());
  160.     static ComponentFunctionUPP COMPONENTSELECTORLOOKUP(short selector_num, ProcInfoType *procInfo);
  161.  
  162.     #if TARGET_OS_MAC && TARGET_CPU_PPC
  163.         // entry point for PowerPC native components
  164.         struct RoutineDescriptor ADD_BASENAME(ComponentDispatchRD) =
  165.           BUILD_ROUTINE_DESCRIPTOR((kPascalStackBased | RESULT_SIZE (kFourByteCode) |
  166.                                     STACK_ROUTINE_PARAMETER (1, kFourByteCode) |
  167.                                     STACK_ROUTINE_PARAMETER (2, kFourByteCode)),COMPONENT_DISPATCH_ENTRY);
  168.     #endif
  169.     
  170.     PASCAL_RTN ComponentResult COMPONENT_DISPATCH_ENTRY(ComponentParameters *params,COMPONENT_GLOBALS())
  171.     {
  172.         ComponentFunctionUPP theProc;
  173.         ComponentResult result = badComponentSelector;
  174.         ProcInfoType theProcInfo;
  175.         
  176.         theProc = COMPONENTSELECTORLOOKUP(params->what, &theProcInfo);
  177.  
  178.         if (theProc) {
  179.             if ( (theProc != kCOMPONENT_ERROR) && (theProc != kCOMPONENT_NOERROR) ) {
  180.                 if (theProcInfo != 0)
  181.                     result = CallComponentFunctionWithStorageProcInfo((Handle) storage, params, (ProcPtr)theProc, theProcInfo);
  182.             }
  183.             else if ( theProc == kCOMPONENT_NOERROR ) {
  184.                 result = noErr;
  185.             }
  186.         }
  187.     #ifdef GET_DELEGATE_COMPONENT
  188.         else
  189.             return DelegateComponentCall(params, GET_DELEGATE_COMPONENT());
  190.     #endif
  191.         return result;
  192.     }
  193. #elif C_DISPATCH_WITH_SWITCH
  194.     PASCAL_RTN ComponentResult COMPONENT_DISPATCH_ENTRY(ComponentParameters *params, COMPONENT_GLOBALS());
  195.     static ComponentFunctionUPP COMPONENTSELECTORLOOKUP(short selector_num);
  196.  
  197.     PASCAL_RTN ComponentResult COMPONENT_DISPATCH_ENTRY( ComponentParameters *params, COMPONENT_GLOBALS() )
  198.         {
  199.         ComponentFunctionUPP theProc;
  200.         
  201.         ComponentResult result = badComponentSelector;
  202.         theProc = COMPONENTSELECTORLOOKUP(params->what);
  203.  
  204.         if (theProc) {
  205.             if ( (theProc != kCOMPONENT_ERROR) && (theProc != kCOMPONENT_NOERROR) ) {
  206.                 result = CallComponentFunctionWithStorage((Handle) storage, params, theProc);
  207.             }
  208.             else if ( theProc == kCOMPONENT_NOERROR ) {
  209.                 result = noErr;
  210.             }
  211.         }
  212.     #ifdef GET_DELEGATE_COMPONENT
  213.         else
  214.             result = DelegateComponentCall(params, GET_DELEGATE_COMPONENT());
  215.     #endif
  216.         return result;
  217.         }
  218. #endif
  219.  
  220. #if C_DISPATCH_WITH_GLOBALS
  221.     typedef struct {
  222.         ComponentFunctionUPP    theProc;
  223.         ProcInfoType            theProcInfo;
  224.     } cdhDispatchInfoRecord;
  225.     
  226.     typedef struct {
  227.         short                    rangeMax;
  228.         cdhDispatchInfoRecord    *cdhDispatchInfoP;
  229.     } cdhRangeDispatchInfoRecord;
  230.     
  231.     #define ComponentSelectorOffset(theOffset)    enum {SelOffset = theOffset};
  232.     
  233.     #define ComponentRangeCount(theCount)        enum {RangeCount = theCount};
  234.     #define ComponentRangeShift(theShift)        enum {RangeShift = theShift};
  235.     #define ComponentRangeMask(theMask)            enum {RangeMask = cdh_GLUE2(0x,theMask)};
  236.     
  237.     #define ComponentStorageType(theType)
  238.     #define ComponentDelegateByteOffset(theOffset)
  239.  
  240.  
  241.     #define StdComponentCall(procName)    \
  242.         (ComponentFunctionUPP)ADD_BASENAME(procName), cdh_GLUE3(uppCallComponent,procName,ProcInfo),
  243.     
  244.     #define ComponentCall(procName)    \
  245.         (ComponentFunctionUPP)ADD_BASENAME(procName), cdh_GLUE3(COMPONENT_UPP_PREFIX(),procName,ProcInfo),
  246.  
  247.     #define ComponentSubTypeCall(procName)    \
  248.         (ComponentFunctionUPP)ADD_BASENAME(procName), cdh_GLUE3(COMPONENT_SUBTYPE_UPP_PREFIX(),procName,ProcInfo),
  249.  
  250.     #define ComponentError(procName)            kCOMPONENT_ERROR, 0,
  251.     
  252.     #define StdComponentNoError(procName)         kCOMPONENT_NOERROR, 0,
  253.     #define ComponentNoError(procName)            kCOMPONENT_NOERROR, 0,
  254.     #define ComponentSubTypeNoError(procName)     kCOMPONENT_NOERROR, 0,
  255.     
  256.     #define ComponentDelegate(procName)            kCOMPONENT_DELEGATE, 0,
  257.     
  258.     
  259.     #define ComponentRangeUnused(rangeNum) \
  260.         static cdhDispatchInfoRecord cdh_GLUE2(cdhDispatchInfo,rangeNum)[1] = { 0 };    \
  261.         enum {cdh_GLUE2(cdhDispatchMax,rangeNum) = 0};
  262.         
  263.     #define ComponentRangeBegin(rangeNum)    \
  264.         static cdhDispatchInfoRecord cdh_GLUE2(cdhDispatchInfo,rangeNum)[] = {
  265.         
  266.     #define ComponentRangeEnd(rangeNum)                \
  267.         };        \
  268.         enum {cdh_GLUE2(cdhDispatchMax,rangeNum) = sizeof(cdh_GLUE2(cdhDispatchInfo,rangeNum)) / sizeof(cdhDispatchInfoRecord)};
  269.     
  270.     #define ComponentComment(theComment)
  271.  
  272.     // define the static dispatch tables
  273.     #include COMPONENT_DISPATCH_FILE
  274.     
  275.     #undef ComponentSelectorOffset
  276.     #undef ComponentRangeCount
  277.     #undef ComponentRangeShift
  278.     #undef ComponentRangeMask
  279.     #undef StdComponentCall
  280.     #undef ComponentCall
  281.     #undef ComponentSubTypeCall
  282.     #undef ComponentError
  283.     #undef StdComponentNoError
  284.     #undef ComponentNoError
  285.     #undef ComponentSubTypeNoError
  286.     #undef ComponentDelegate
  287.     #undef ComponentRangeUnused
  288.     #undef ComponentRangeBegin
  289.     #undef ComponentRangeEnd    
  290.     
  291.     #define ComponentSelectorOffset(theOffset)
  292.     #define ComponentRangeCount(theCount)
  293.     #define ComponentRangeShift(theShift)
  294.     #define ComponentRangeMask(theMask)
  295.     #define StdComponentCall(procName)
  296.     #define ComponentCall(procName)
  297.     #define ComponentSubTypeCall(procName)
  298.     #define ComponentError(procName)
  299.     #define StdComponentNoError(procName)
  300.     #define ComponentNoError(procName)
  301.     #define ComponentSubTypeNoError(procName)
  302.     #define ComponentDelegate(procName)
  303.     
  304.     #define ComponentRangeUnused(rangeNum) \
  305.         { 0, nil },
  306.     #define ComponentRangeBegin(rangeNum)        \
  307.         { cdh_GLUE2(cdhDispatchMax,rangeNum), cdh_GLUE2(cdhDispatchInfo,rangeNum) },
  308.     #define ComponentRangeEnd(rangeNum)
  309.     
  310.     // define the static range tables (max per range and point to dispatch tables)
  311.     static cdhRangeDispatchInfoRecord cdhRangeDispatch[RangeCount+1] = {
  312.         #include COMPONENT_DISPATCH_FILE
  313.     };
  314.     
  315.     ComponentFunctionUPP COMPONENTSELECTORLOOKUP(short selector_num, ProcInfoType *procInfo)
  316.     {
  317.         ProcInfoType pinfo = 0;
  318.         ComponentFunctionUPP result = kCOMPONENT_DELEGATE;
  319.         cdhDispatchInfoRecord *infoP = nil;
  320.         short theRange;
  321.         
  322.         theRange = selector_num >> RangeShift;
  323.         if (theRange < 0) {
  324.             selector_num += SelOffset;
  325.             if (selector_num >= 0) {
  326.                 infoP = &(cdhRangeDispatch[0].cdhDispatchInfoP)[selector_num];
  327.             }
  328.         } else {
  329.             if (theRange < RangeCount) {
  330.                 selector_num &= RangeMask;
  331.                 if (selector_num < cdhRangeDispatch[theRange+1].rangeMax)
  332.                     infoP = &(cdhRangeDispatch[theRange+1].cdhDispatchInfoP)[selector_num];
  333.             }
  334.         }
  335.         
  336.         if (infoP) {
  337.             *procInfo = infoP->theProcInfo;
  338.             result = infoP->theProc;
  339.         } 
  340.         return result;
  341.     }
  342.  
  343. #elif C_DISPATCH_WITH_SWITCH
  344.     ComponentFunctionUPP COMPONENTSELECTORLOOKUP( short selector_num )
  345.     {
  346.         ComponentFunctionUPP aProc = (ComponentFunctionUPP) kCOMPONENT_DELEGATE;
  347.     
  348.         #define ComponentSelectorOffset(theOffset)
  349.  
  350.         #define    case_ComponentCall(kPrefix,procName)    case cdh_GLUE3(kPrefix,procName,Select): aProc = (ComponentFunctionUPP)ADD_BASENAME(procName); break;
  351.         #define StdComponentCall(procName)                case_ComponentCall(kComponent,procName)
  352.         #define ComponentCall(procName)                    case_ComponentCall(COMPONENT_SELECT_PREFIX(),procName)
  353.         #define ComponentSubTypeCall(procName)            case_ComponentCall(COMPONENT_SUBTYPE_SELECT_PREFIX(),procName)
  354.  
  355.         #define    case_ComponentNoError(kPrefix,procName)    case cdh_GLUE3(kPrefix,procName,Select): aProc = (ComponentFunctionUPP)kCOMPONENT_NOERROR; break;
  356.         #define StdComponentNoError(procName)            case_ComponentNoError(kComponent,procName)
  357.         #define ComponentNoError(procName)                case_ComponentNoError(COMPONENT_SELECT_PREFIX(),procName)
  358.         #define ComponentSubTypeNoError(procName)        case_ComponentNoError(COMPONENT_SUBTYPE_SELECT_PREFIX(),procName)
  359.  
  360.         #define ComponentError(procName)                //ComponentError for C_DISPATCH_WITH_SWITCH uses default case (delegate if we can)
  361.  
  362.         #define ComponentDelegate(procName)                //The default case for C_DISPATCH_WITH_SWITCH is to delegate if we can, error if we can't
  363.         
  364.         #define ComponentRangeCount(theCount)
  365.         #define ComponentRangeShift(theShift)
  366.         #define ComponentRangeMask(theMask)
  367.         #define ComponentRangeBegin(rangeNum)
  368.         #define ComponentRangeEnd(rangeNum)
  369.         #define ComponentRangeUnused(rangeNum)
  370.         #define ComponentStorageType(theType)
  371.         #define ComponentDelegateByteOffset(theOffset)
  372.         #define ComponentComment(theComment)
  373.  
  374.         switch (selector_num) {
  375.             #include COMPONENT_DISPATCH_FILE
  376.             }
  377.     
  378.         return aProc;
  379.     }
  380. #endif
  381.  
  382. #ifdef OVERRIDE_CANDO
  383.     ComponentResult OVERRIDE_CANDO(Handle storage, short ftnNumber, ComponentResult result);
  384. #endif
  385.  
  386. PASCAL_RTN ComponentResult ADD_BASENAME(CanDo)( COMPONENT_GLOBALS(), short ftnNumber );
  387. PASCAL_RTN ComponentResult ADD_BASENAME(CanDo)( COMPONENT_GLOBALS(), short ftnNumber )
  388. {
  389.     ComponentResult    result;
  390. #if C_DISPATCH_WITH_GLOBALS
  391.     ProcInfoType ignore;
  392.     result = (ComponentResult) COMPONENTSELECTORLOOKUP(ftnNumber, &ignore);
  393. #else
  394.     result = (ComponentResult) COMPONENTSELECTORLOOKUP(ftnNumber);
  395. #endif
  396.     
  397.     /* check for a ComponentError */
  398.     if ( result == (ComponentResult) kCOMPONENT_ERROR )
  399.         result = false;
  400.     else if ( result == (ComponentResult) kCOMPONENT_DELEGATE )
  401.         result = false;
  402.     else
  403.         result = true;
  404.  
  405. #ifdef OVERRIDE_CANDO
  406.     result = OVERRIDE_CANDO( storage, ftnNumber, result);
  407. #endif
  408.  
  409. #ifdef GET_DELEGATE_COMPONENT
  410.     /* if we're delegated, then keep looking */
  411.     if (!result)
  412.         {
  413.         if (GET_DELEGATE_COMPONENT())
  414.             result = CallComponentCanDo( GET_DELEGATE_COMPONENT(), ftnNumber );
  415.         }
  416. #endif
  417.  
  418.     return result;
  419. }
  420.  
  421.